package com.apestech.api.condition.control;

import com.apestech.framework.db.SqlResultSet;
import com.apestech.framework.db.SqlSession;
import com.apestech.framework.db.callback.QueryCallBackHandler;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.callback.SpiltStrCallback;
import com.apestech.framework.util.callback.SpiltStrCallbackReturn;
import com.apestech.framework.xml.condition.modul.Condition;
import com.apestech.framework.xml.condition.modul.Field;
import com.apestech.framework.xml.table.modul.Tables;

import java.util.ArrayList;

public class ConditionBase extends ControlUtil implements ConditionLifeCycleInter {
    private Condition condition;
    private JSONObject input;

    private String SYS_NO_CHECK;
    private JSONArray result;
    private JSONObject param;
    private SqlSession session;
    private ArrayList<String> msg=new ArrayList<String>();

    private String etab=null;
    private String ekey=null;

    public ConditionBase(Condition condition, JSONObject input){
        this.input=input;
        this.condition=condition;
        SYS_NO_CHECK=input.getString("SYS_NO_CHECK");
        session=condition.getSession();
    }

    @Override
    public boolean iniCheck(Tables tab) throws Exception {
        /*
        1)表是否存在
        2)是否有配置SYS_NOTHING
        3)主键判断，如果数据不完整将不执行
        */
        etab=tab.getExecTable();
        if(!session.tableExists(etab)){
            msg.add("表["+etab+"]没有建表成功，请补充对其saveResultMap的初始化操作！");
            return false;
        }
        ekey=tab.getTable(etab).getPrimaryField();
        if(ekey==null){
            msg.add("表["+etab+"]没有主键字段，不能参与计算，请检查表结构配置逻辑！");
            return false;
        }
        param=getKeyInput(session, etab, ekey, input);

        return execSplitStr(ekey,",", new SpiltStrCallbackReturn(){
            @Override
            public boolean exec(String id) throws Exception {
                String startDateId=session.getSpecialField().getStartDate();
                String endDateId=session.getSpecialField().getEndDate();
                if(id.equals(startDateId)) {
                    if(input.get(startDateId)==null && input.get("SYS_RQ")==null){
                        msg.add("SYS_RQ或"+startDateId+"值为空，请检查入参信息！");
                        return false;
                    }
                } else if(id.equals(endDateId)) {
                    if (input.get(endDateId)==null && input.get("SYS_RQ")==null) {
                        msg.add("SYS_RQ或"+endDateId+"值为空，请检查入参信息！");
                        return false;
                    }
                } else {
                    if(input.get(id)==null){
                        if(SYS_NO_CHECK==null || (","+SYS_NO_CHECK+",").indexOf(","+id+",")<0){
                            msg.add(id+"值为空，请检查入参信息！");
                            return false;
                        }
                    }
                }
                return true;
            }
        });
    }

    @Override
    public void getOrderSql() throws Exception {
        final String[] order = {""};
        String tree=input.getString("SYS_TREE_FIELD");
        input.remove("SYS_TREE_FIELD");
        if(tree!=null){
            execSplitStr(tree, ",", new SpiltStrCallback(){
                @Override
                public void exec(String id) throws Exception {
                    if(!"".equals(order[0])){
                        order[0]=order[0]+",";
                    }
                    order[0] = order[0] +"A."+id+" DESC ";
                }
            });
        }
        String sOrder=" @WHERE@ ORDER BY ";  //AND ROWNUM=1
        if(!"".equals(order[0])){
            sOrder=sOrder+order[0]+",";
        }
        sOrder=sOrder+" A." + session.getSpecialField().getConditionId() + " DESC ";
        param.put("nb_order", sOrder);
    }

    @Override
    public boolean exec(Tables tab) throws Exception {
        result=new JSONArray();
        String SYS_DIM_FIELD=input.getString("SYS_DIM_FIELD");
        session.getForResultSet().table(etab,param, new QueryCallBackHandler(){
            @Override
            public void getData(SqlResultSet rs, JSONArray rslist) throws Exception {
                if(SYS_DIM_FIELD!=null){
                    while(rs.next()){
                        saveParam(rs);
                        JSONObject json=new JSONObject();
                        json.putAll(param);
                        json.remove("condition");
                        json.remove("autoCompletion");
                        result.add(json);
                    }
                } else {
                    if(rs.next()){
                        saveParam(rs);
                        param.put("break","1");
                    }
                }
            }
        });
        if(param.get("break")!=null){
            param.remove("break");
            return true;
        }
        return false;
    }

    private void saveParam(SqlResultSet rs) throws Exception {
        JSONObject o=new JSONObject();
        ArrayList<Field> fields=condition.getControlFields();
        int fieldsize=fields.size();
        JSONObject m=rs.toRowJson();
        param.put("C_ID", m.getString("ID"));
        if("2".equals(condition.getControlType())){
            param.put("result",true);
        } else {
            m.put("SYS_NO_CHECK", input.getString("SYS_NO_CHECK"));
            if(SYS_NO_CHECK!=null){
                execSplitStr(SYS_NO_CHECK, ",", new SpiltStrCallback() {
                    @Override
                    public void exec(String id) throws Exception {
                        param.put(id, m.get(id));
                    }
                });
            }
            saveResultMap(fields, fieldsize, m, param);
        }
        param.put("CONDITION_ID", condition.getId());
        param.put("CONDITION_NAME", condition.getName());
    }

    @Override
    public JSONObject finiExec() throws Exception {
        if(param!=null && param.size()==0){
            if("2".equals(condition.getControlType())){
                param.put("result",false);
            } else {
                param=saveEmptyResultMap();
                param.put("sys_break","1");
            }
        }
        return param;
    }

    public JSONObject getParam() {
        return param;
    }

    public void saveResultMap(ArrayList<Field> fields, int fieldsize, JSONObject input, JSONObject output) throws Exception {
        JSONObject o=new JSONObject();
        for(int i=0; i<fieldsize; i++){
            String id=fields.get(i).getField();
            output.put(id, input.get(id));
            o.put("("+fields.get(i).getField()+")"+fields.get(i).getName(), input.get(id));
        }
        output.put("RESULT_DATA", o);
    }

    public JSONObject saveEmptyResultMap() throws Exception {
        JSONObject map=new JSONObject();
        ArrayList<Field> fields=condition.getControlFields();
        int len=fields.size();
        for(int i=0; i<len; i++){
            String sid=fields.get(i).getId();
            if("JE".equals(sid) || "BL".equals(sid) || fields.get(i).getType().indexOf("NUMBER")>=0){
                map.put(fields.get(i).getField(), 0);
            }
        }
        return map;
    }

    public ArrayList<String> getMsg() {
        return msg;
    }

    public Condition getCondition() {
        return condition;
    }

    public SqlSession getSession() {
        return session;
    }

    public JSONObject getInput() {
        return input;
    }

    public JSONArray getResult() {
        return result;
    }


}
